﻿using Microsoft.Extensions.Configuration;
using OConf.Common;
using OConf.Entity;
using OConf.IBLL;
using OConf.Model.Common;
using OConf.Model.RequestInput.CNameSpace;
using OConf.Model.RequestInput.ConfigInfo;
using OConf.Model.RequestInput.ProjectInfo;
using OConf.Service;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace OConf.BLL
{
    public class CNameSpaceBLL: ICNameSpaceBLL
    {
        private readonly CNameSpaceService _cNameSpaceService;
        private readonly ProjectInfoService _projectInfoService;
        private readonly VersionsService _versionsService;
        private readonly IConfiguration _configuration;

        public CNameSpaceBLL(IConfiguration configuration)
        {
            _cNameSpaceService = new CNameSpaceService(configuration);
            _projectInfoService = new ProjectInfoService(configuration);
            _versionsService = new VersionsService(configuration);
            _configuration = configuration;
        }

        /// <summary>
        /// 新增命名空间信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ReturnData<bool> AddCNameSpace(AddCNameSpaceInput input)
        {
            try
            {
                if (!_projectInfoService.IsExists(input.ProjectID))
                {
                    return ReturnDataHelper<bool>.NoExists("项目信息不存在", false);
                }

                if (_cNameSpaceService.IsExistByNameSpaceProID(input.NameSpace, input.ProjectID))
                {
                    return ReturnDataHelper<bool>.Exists("命名空间已存在", false);
                }

                CNameSpaceEntity entity = new CNameSpaceEntity()
                {
                    ID = Guid.NewGuid().ToString("N"),
                    NameSpace = input.NameSpace,
                    ProjectID = input.ProjectID,
                    Createtime = DateTime.Now,
                    IsPublish = true
                };

                _cNameSpaceService.AddEntity(entity);

                return ReturnDataHelper<bool>.Success("操作成功", true);
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteExceptionLog("AddCNameSpace,新增命名空间信息", ex);
                return ReturnDataHelper<bool>.Fail("系统异常", false);
            }
        }

        /// <summary>
        /// 删除命名空间
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ReturnData<bool> DeleteCNameSpace(DeleteCNameSpaceInput input)
        {
            try
            {
                CNameSpaceEntity cNameSpace = _cNameSpaceService.FindEntity(input.ID);
                if (cNameSpace == null)
                {
                    return ReturnDataHelper<bool>.NoExists("命名空间不存在", false);
                }
                _cNameSpaceService.DeleteByTran(input.ID);

                //删除配置缓存文件
                ProjectInfoEntity projectInfo = _projectInfoService.FindEnity(cNameSpace.ProjectID);
                if (projectInfo != null)
                {
                    string fileDirPath = Path.Combine(GlobalValues.ConfigFileSaveDirPath, projectInfo.ProjectName);
                    string filePath = Path.Combine(fileDirPath, $"{cNameSpace.NameSpace}.json");
                    FileCore.DeleteFile(filePath);
                }

                return ReturnDataHelper<bool>.Success("操作成功", true);
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteExceptionLog("DeleteCNameSpace,删除命名空间", ex);
                return ReturnDataHelper<bool>.Fail("系统异常", false);
            }
        }

        /// <summary>
        /// 获取命名空间列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ReturnData<List<CNameSpaceModel>> GetCNameSpaceList(GetNameSpaceInput input)
        {
            try
            {
                List<CNameSpaceEntity> list = _cNameSpaceService.GetList(input.ProjectID);
                List<CNameSpaceModel> result = list.Select(w => new CNameSpaceModel()
                {
                    ID = w.ID,
                    NameSpace = w.NameSpace,
                    ProjectID = w.ProjectID,
                    Createtime = w.Createtime,
                    IsPublish = w.IsPublish
                }).ToList();

                return ReturnDataHelper<List<CNameSpaceModel>>.Success("操作成功", result);
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteExceptionLog("GetCNameSpaceList,获取命名空间列表", ex);
                return ReturnDataHelper<List<CNameSpaceModel>>.Fail("系统异常", null);
            }
        }

        /// <summary>
        /// 获取NameSpace信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ReturnData<CNameSpaceModel> GetCNameSpaceModel(GetNameSpaceDetailInput input)
        {
            try
            {
                CNameSpaceEntity model = _cNameSpaceService.FindEntity(input.ID);
                if (model == null)
                {
                    return ReturnDataHelper<CNameSpaceModel>.NoExists("命名空间不存在", null);
                }

                CNameSpaceModel result = new CNameSpaceModel()
                {
                    ID = model.ID,
                    NameSpace = model.NameSpace,
                    ProjectID = model.ProjectID,
                    Createtime = model.Createtime,
                    IsPublish = model.IsPublish
                };

                return ReturnDataHelper<CNameSpaceModel>.Success("操作成功", result);
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteExceptionLog("GetCNameSpaceModel,获取NameSpace信息", ex);
                return ReturnDataHelper<CNameSpaceModel>.Fail("系统异常", null);
            }
        }

        /// <summary>
        /// 发布配置信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ReturnData<BackProgramConfigInfo> PublishConfigInfo(PublishConfigInput input)
        {
            try
            {
                CNameSpaceEntity cNameSpace = _cNameSpaceService.FindEntity(input.NameSpaceID);
                if (cNameSpace == null)
                {
                    return ReturnDataHelper<BackProgramConfigInfo>.NoExists("NameSpace不存在", null);
                }
                if (cNameSpace.IsPublish)
                {
                    return ReturnDataHelper<BackProgramConfigInfo>.Fail("已发布", null);
                }

                ProjectInfoEntity projectInfo = _projectInfoService.FindEnity(cNameSpace.ProjectID);
                if (projectInfo == null)
                {
                    return ReturnDataHelper<BackProgramConfigInfo>.NoExists("项目信息不存在", null);
                }

                long nowTime = TimeCore.GetNowTimeOffset();
                VersionsEntity version = new VersionsEntity()
                {
                    ID = Guid.NewGuid().ToString("N"),
                    ProjectID = cNameSpace.ProjectID,
                    NameSpaceID = input.NameSpaceID,
                    VersionNo = $"{cNameSpace.NameSpace}-{nowTime}",
                    Createtime = DateTime.Now
                };

                //更新NameSpace发布状态，更新ProjectInfo的最后发布时间，更新ConfigInfo状态
                _cNameSpaceService.PublishNameSpaceByTran(cNameSpace.ID, cNameSpace.ProjectID, nowTime, version);

                //生成Json文件
                new ProjectInfoBLL(_configuration).CreateJsonFile(projectInfo, cNameSpace);

                BackProgramConfigInfo result = ProjectInfoBLL.GetConfigInfoFromJsonFile(projectInfo.ProjectName, cNameSpace.NameSpace, nowTime);

                //删除过期的版本信息
                DeleteExpiredVersionData(cNameSpace.ID);

                return ReturnDataHelper<BackProgramConfigInfo>.Success("操作成功", result);
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteExceptionLog("PublishConfigInfo,发布配置信息", ex);
                return ReturnDataHelper<BackProgramConfigInfo>.Exception("系统异常", null);
            }
        }

        /// <summary>
        /// 删除过期的版本信息（同一个命名空间下只保留最近20条版本信息）
        /// </summary>
        /// <returns></returns>
        internal bool DeleteExpiredVersionData(string nameSpaceId)
        {
            try
            {
                var expredVerIds = _versionsService.GetExpiredIDs(nameSpaceId);
                foreach (var verId in expredVerIds)
                {
                    _versionsService.DeleteVersionAndConfigByTran(verId);
                }
                return true;
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteExceptionLog($"DeleteExpiredVersionData,删除过期的版本信息,NameSpaceId：{nameSpaceId}", ex);
                return false;
            }
        }
    }
}
